import { checkStatus, cryptoInterceptorsRequest, mixinDefaultConfig } from "@/api/helper";
import { $themeConfig } from "@/@CORE/app-config";
import { LOGIN_URL } from "@/@CORE/app-config/config";
import router from "@/router";
import { GlobalStore } from "@/stores";
import axios from "axios";
import { showFullScreenLoading, tryHideFullScreenLoading } from "@/@CORE/app-config/serviceLoading";

import { ElNotification } from "element-plus";
import { ElMessage } from "element-plus";

// eslint-disable-next-line
import { STATUS_FIELD, STATUS_ERROR, STATUS_SUCCESS, STATUS_LOGIN_EXPIRED } from "@CORE/app-config/request";
const {
	http: { BASE_URL, TIME_OUT }
} = $themeConfig;

const config = {
	baseURL: import.meta.env.VITE_API_BASE_URL || BASE_URL,
	timeout: import.meta.env.VITE_API_TIMEOUT || TIME_OUT,
	withCredentials: false
};
const loadingConfig = {
	text: "正在加载中...",
	background: "rgba(0, 0, 0, 0.7)"
};

class RequestHttp {
	constructor(config) {
		this.service = axios.create(config);
		this.interceptorsRequest();
		this.interceptorsResponse();
	}
	interceptorsRequest() {
		this.service.interceptors.request.use(
			config => {
				const globalStore = GlobalStore();
				config.config = mixinDefaultConfig(config);
				config?.config?.noLoading || showFullScreenLoading(loadingConfig);

				config = cryptoInterceptorsRequest(config);
				const token = globalStore.token;
				if (token) {
					config.headers.Authorization = token;
				}
				return {
					...config,
					headers: { ...config.headers }
				};
			},
			error => {
				return Promise.reject(error);
			}
		);
	}
	interceptorsResponse() {
		this.service.interceptors.response.use(
			response => {
				const { data } = response;
				const {
					config: { config: interConfig }
				} = response;
				// eslint-disable-next-line
				const globalStore = GlobalStore();
				// * 在请求结束后，并关闭请求 loading
				tryHideFullScreenLoading();
				// * 登陆失效（code == 401）
				if (data[STATUS_FIELD] === STATUS_LOGIN_EXPIRED) {
					interConfig.failShowMessage && ElMessage.error(data.msg);
					router.replace(LOGIN_URL);
					if (interConfig.failShowNotification) {
						ElNotification({
							title: "错误",
							message: data.msg,
							type: "error",
							duration: 3000,
							offset: 60
						});
					}
					return Promise.reject(data);
				}
				// * 全局错误信息拦截（防止下载文件得时候返回数据流，没有code，直接报错）
				if (data[STATUS_FIELD] && data[STATUS_FIELD] !== STATUS_SUCCESS) {
					ElMessage.error(data.msg);
					return Promise.reject(data);
				}
				// * 成功请求（在页面上除非特殊情况，否则不用在页面处理失败逻辑）
				return data;
			},
			async error => {
				const { response } = error;
				tryHideFullScreenLoading();
				// 请求超时 && 网络错误单独判断，没有 response
				if (error.message.indexOf("timeout") !== -1) ElMessage.error("请求超时！请您稍后重试");
				if (error.message.indexOf("Network Error") !== -1) {
					ElMessage.error("网络错误！请您稍后重试");
					router.replace(LOGIN_URL);
				}

				// 根据响应的错误状态码，做不同的处理
				if (response) checkStatus(response.status);
				// 服务器结果都没有返回(可能服务器错误可能客户端断网)，断网处理:可以跳转到断网页面
				if (!window.navigator.onLine) await router.replace("/500");
				return Promise.reject(error.response.data);
			}
		);
	}

	get(url, params = {}, _object = {}) {
		return this.service.get(url, { params, ..._object });
	}
	post(url, params = {}, _object = {}) {
		return this.service.post(url, params, _object);
	}
	put(url, params = {}, _object = {}) {
		return this.service.put(url, params, _object);
	}
	delete(url, params = {}, _object = {}) {
		return this.service.delete(url, { params, ..._object });
	}
	download(url, params = {}, _object = {}) {
		return this.service.post(url, params, { ..._object, responseType: "blob" });
	}
}
export default new RequestHttp(config);
